function Path(a, e) {
    var s = new Array();
    var k = a;
    var d;
    var c;
    var q;
    var h;
    var m = 3;
    var b = 9;
    var n = new Array();
    var g = 1;
    var f = 1;
    var x = 0;
    var w = 0;
    var r = 0;
    var o = 0;
    var v = e;
    var l = new Array();
    var j = new Array();
    var u;
    var t;
    var i = 0;
    this.findIndexOf = function (z, B) {
        if (!Array.indexOf) {
            for (var A = 0; A < z.length; A++) {
                if (z[A] == B) {
                    return A;
                }
            }
            return -1;
        } else {
            return z.indexOf(B);
        }
    };
    var p = function (E, C) {
        var D = 0;
        var B = 0;
        if (r > 0) {
            D = s[r - 1].getX();
            B = s[r - 1].getY();
            if (E < D + m && E > D - m && C < B + m && C > B - m) {
                return false;
            } else {
                while (E > D + b || E < D - b || C > B + b || C < B - b) {
                    var A = Math.round((E - D) * 0.5);
                    var z = Math.round((C - B) * 0.5);
                    if (A > 0 && A > b) {
                        A = b;
                    }
                    if (A < 0 && A < -b) {
                        A = -b;
                    }
                    if (z > 0 && z > b) {
                        z = b;
                    }
                    if (z < 0 && z < -b) {
                        z = -b;
                    }
                    var G = D + A;
                    var F = B + z;
                    y(G, F, true);
                    D = G;
                    B = F;
                }
            }
        }
        y(E, C, false);
        return true;
    };
    this.quickDrawNode = function (C, B) {
        if (i > 0) {
            if (Math.abs(u - C) < 5 && Math.abs(t - B) < 5) {
                return;
            }
        }
        l.push(C);
        j.push(B);
        i++;
        if (i > 1) {
            var A = ['M', u, ' ', t, 'L', C, ' ', B].join();
            var z = k.path(A);
        } else {
            var A = ['M', C, ' ', B, 'L', C + 3, ' ', B + 1].join();
            var z = k.path(A);
        }
        z.attr('stroke-width', 3);
        z.attr('stroke', v);
        n.push(z);
        o++;
        u = C;
        t = B;
    };
    this.finalizePath = function () {
        for (var z = 0; z < i; z++) {
            p(l[z], j[z]);
        }
    };
    var y = function (C, B, A) {
        var z = new Node(C, B, this, A);
        if (r == 0) {
            c = new Rectangle(C, B, C, B);
            q = z;
        } else {
            c.addPoint(C, B);
            if (z.getY() > q.getY()) {
                q = z;
            }
        }
        s.push(z);
        r++;
    };
    this.clearDisplay = function () {
        if (o > 0) {
            for (var z = 0; z < o; z++) {
                n[z].remove();
            }
            n = new Array();
            o = 0;
        }
        if (d != null) {
            d.remove();
            d = null;
        }
    };
    this.draw = function (C, z, E) {
        if (o > 0) {
            for (var D = 0; D < o; D++) {
                n[D].remove();
            }
            n = new Array();
            o = 0;
        }
        if (z == null) {
            z = 0;
        }
        if (E == null) {
            E = 0;
        }
        if (r > 0) {
            if (C == null) {
                var B = ['M', (s[0].getX() + z) * g + x, ' ', (s[0].getY() + E) * f + w];
                if (r == 1) {
                    B.push('L');
                    B.push((s[0].getX() + 2 + z) * g + x);
                    B.push(' ');
                    B.push((s[0].getY() + 3 + E) * f + w);
                } else {
                    for (var A = 1; A < r; A++) {
                        if (s[A].isExtraNode() == false) {
                            B.push('L');
                            B.push((s[A].getX() + z) * g + x);
                            B.push(' ');
                            B.push((s[A].getY() + E) * f + w);
                        }
                    }
                }
            } else {
                var B = ['M', (C.distortPointX(s[0].getX(), s[0].getY()) + z) * g + x, ' ', (C.distortPointY(s[0].getX(), s[0].getY()) + E) * f + w];
                if (r == 1) {
                    B.push('L');
                    B.push((C.distortPointX(s[0].getX() + 2, s[0].getY() + 3) + z) * g + x);
                    B.push(' ');
                    B.push((C.distortPointY(s[0].getX() + 2, s[0].getY() + 3) + E) * f + w);
                } else {
                    for (var A = 1; A < r; A++) {
                        if (s[A].isExtraNode() == false) {
                            B.push('L');
                            B.push((C.distortPointX(s[A].getX(), s[A].getY()) + z) * g + x);
                            B.push(' ');
                            B.push((C.distortPointY(s[A].getX(), s[A].getY()) + E) * f + w);
                        }
                    }
                }
            }
            if (d == null) {
                d = k.path(B.join());
                d.attr('stroke-width', 3 * g);
                d.attr('stroke', v);
            } else {
                d.attr('path', B);
            }
        }
    };
    this.drawLastPoint = function () {
        if (r > 1) {
            var D = r - 1;
            var z = o + 1;
            for (var C = z; C <= D; C++) {
                var B = 'M' + s[C - 1].getX() + ' ' + s[C - 1].getY();
                B += 'L' + s[C].getX() + ' ' + s[C].getY();
                var A = k.path(B);
                A.attr('stroke-width', 3);
                A.attr('stroke', v);
                n.push(A);
                o++;
            }
        } else {
            if (r == 1) {
                var B = 'M' + s[0].getX() + ' ' + s[0].getY();
                B += 'L' + (s[0].getX() + 1) + ' ' + (s[0].getY() + 1);
                var A = k.path(B);
                A.attr('stroke-width', 3);
                A.attr('stroke', v);
                n.push(A);
                o++;
            }
        }
    };
    this.getLowestNode = function () {
        return q;
    };
    this.getNumNodes = function () {
        return i;
    };
    this.getSecondLowestNode = function () {
        var z = this.findIndexOf(s, q);
        var C = q.getY();
        var A = false;
        for (var B = z; B < r; B++) {
            if (A == false) {
                if (s[B].getY() < C - h) {
                    A = true;
                }
            } else {
                if (s[B].getY() > C + h * 0.5) {
                    return s[B];
                }
            }
        }
        A = false;
        for (var B = z; B >= 0; B--) {
            if (A == false) {
                if (s[B].getY() < C - h) {
                    A = true;
                }
            } else {
                if (s[B].getY() > C + h * 0.5) {
                    return s[B];
                }
            }
        }
        return null;
    };
    this.getRect = function () {
        return c;
    };
    this.getNodesInRow = function (z, C) {
        var B = new Array();
        if (c.bottom >= z && c.top <= C) {
            for (var A = 0; A < r; A++) {
                if (s[A].getY() >= z && s[A].getY() <= C) {
                    B.push(s[A]);
                }
            }
        }
        return B;
    };
    this.highlightNodes = function () {
        for (var z = 0; z < r; z++) {
            var A = k.circle(s[z].getX(), s[z].getY(), 2, 2, 0).attr({ fill: '#ff0', opacity: 0.5 });
        }
    };
    this.setScale = function (C, B, A, z) {
        x = C;
        w = B;
        g = A;
        f = z;
    };
    this.removeDeletedNodes = function () {
        var B = Array();
        var A = 0;
        for (var z = 0; z < r; z++) {
            if (s[z].isMarkedForDelete() == false) {
                B.push(s[z]);
                A++;
            }
        }
        s = B;
        r = A;
    };
}
